#pragma once

#include "INode.h"
#include "UCS.h"

struct PointMatrix3D;
class QUndoStack;
struct ScenePrivate;
class JsonReader;
class FormulaManager;
class TopoDS_Face;
class Scene : public IRoot
{
	Q_OBJECT
public:
	Scene(QObject* parent, QUndoStack* undoStack);
	~Scene();

	virtual void addChild(const std::shared_ptr<INode>& pChild) override;
	virtual void removeChild(const std::shared_ptr<INode>& pChild) override;
	void removeChildren();
	const std::set<std::shared_ptr<INode>>& getChildren() const;
	void updateColor();
	//get INode::m_id from ConstructTreeModel row
	int modelRow2ConstructID(int row) const;
	//get ConstructTreeModel row from INode::m_id 
	int constructID2ModelRow(int id) const;

	QUndoStack* undoStack() const;

	void save(QJsonObject& json) const;
	void load(const QJsonObject& json);
	void newFile();

	bool snapPoint(PointMatrix3D & point);
	void setPicker(Qt3DPicker* picker);
	void setCurrentUCS(UCSKind kind);
	void setUCS(UCSKind kind, UCS* ucs);
	void setUCSOrigin(const osg::Vec3d& pos);
	std::shared_ptr<UCS> getCurrentUCS() const;
	std::vector<std::shared_ptr<UCS>> getUCS() const;
	UCSKind getCurrentUCSIndex() const;
	virtual Qt3DPicker* getPicker() const override;
	virtual osg::Node* getRep3D() const override;
	osg::Node* getRoot3D() const;
	virtual void update3D() override;
	virtual void visitChildren(INodeCallback lcb, bool preorder) const override;
	
	void showSnapPoint(const osg::Vec3d& pos);
	void hideSnapPoint();
	osg::ref_ptr<osg::Geometry> getSnapPoint() const;
	void build3DXPoints();
	std::vector<osg::Vec3d> get3DXPoints();
	void pauseBuild3DXPoints();
	void restoreBuild3DXPoints();
	QJsonObject exportBrep();
	std::vector<TopoDS_Face> getFaces() const;

	void getRange(int& maxX, int& maxY, int& maxZ) const;
	void setRange(int maxX, int maxY, int maxZ);

	void showAllFace();

private:
	void userFeedback(const std::set<osg::Node*>& selected) const;

	ScenePrivate* d_ptr;
};
